Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: macOS feasibility incorporation #71

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

saleha-muzammil
Copy link
Contributor

@saleha-muzammil saleha-muzammil commented Nov 3, 2024

Description:

Making PROBE feasible for macOS systems.

Changes:

  • Worked out how to interpose in macOS, added a test program (test_program.c), which interposes the fopen call and calls the underlying call. The mentioned changes are in files interpose.h , interpose.c , test_program.c . Steps to run test_program.c with interposition:

    • clang -dynamiclib -o libinterpose.dylib interpose.c
    • clang -o test_program test_program.c
    • export DYLD_INSERT_LIBRARIES=$(pwd)/libinterpose.dylib
    • ./test_program
  • Added macOS architecture in flake.nix

  • Edited Makefile to be adjustable for both linux and macOS.

  • The rest of the changes have been made either to add replacement libraries for macOS, added ifndef with code blocks which are linux or macOS specific. Added dummy definitions like typedef thrd_t int for macros which are not available on macOS. Guarded dummy definitions with ifndef

Questions and next steps:

  • Which operations to interpose, what to do in cases where corresponding functions or alternatives are not available in macOS

@saleha-muzammil saleha-muzammil marked this pull request as draft November 3, 2024 20:15
@saleha-muzammil saleha-muzammil marked this pull request as ready for review November 3, 2024 20:21
@@ -37,35 +42,37 @@ int copy(const struct Path* path) {
* We promise not to read those fields in this function.
*/
static void prov_log_try(struct Op op) {
#ifdef CLONE_VFORK
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we not need this ifdef since x & CLONE_VFORK will always be 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incorporated ( removed CLONE_VFORKdefinition from prov_buffer.c )

* Generate a macOS interpose struct
* Types from: http://opensource.apple.com/source/dyld/dyld-210.2.3/include/mach-o/dyld-interposing.h
*/
#define OSX_INTERPOSE_STRUCT(NEW, OLD) \
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally, pre-processor macros would be the right way to eliminate duplicated code.

In this particular case, the C code is generated from Python in generator/gen_libc_hooks.py, and there isn't a good way to emit code that calls the C preprocessor macros. It would be better to implement the logic directly in Python.

Therefore, for the above file, can you write out what it should be after expanding the pre-processor macros?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is that in Linux, the shared library needs to define a function with the name we want to interpose (e.g., open), and load the real/underlying function with a new name (e.g., unwrapped_open) using dlsym.

In Mac, it seems that we define a function with the new name (e.g., my_open), and call the real/underlying function with the original name (open)

__attribute__ ((section ("__DATA,__interpose"))) = {
    (const void*)(unsigned long)&my_open,
    (const void*)(unsigned long)&open
};

The meaning of the name open is reversed: in Linux its the wrapper; in Mac it's the underlying function.

Copy link
Owner

@charmoniumQ charmoniumQ Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is of course salvageable. We should always call unwrapped_open and wrapped_open to eliminate confusion, but alias one of them to the "original name" based on platform.

#ifdef linux
#define wrapped_open open
#else if apple
#define unwrapped_open open
#endif

We hardly ever call the wrapped versions, always the unwrapped, which are already called as unwrapped_ in our code.

But I wanted to confirm that this is the only way to interpose functions in Mac before doing that. So please let me know.

@saleha-muzammil saleha-muzammil changed the title feat: macOS feasibility incorporations feat: macOS feasibility incorporation Nov 10, 2024
Saleha and others added 4 commits February 14, 2025 22:21
Co-authored-by: Jenna Fligor <[email protected]>
Co-authored-by: Jenna Fligor <[email protected]>
Co-authored-by: Jenna Fligor <[email protected]>
Comment on lines +203 to +218
if (!__process_inited) {
__process_inited = true;

DEBUG("Initializing process");
init_function_pointers();
check_function_pointers();
init_process_global_state();

pthread_key_create(&tld_key, free);

__process_inited_done = true;
}
while (!__process_inited_done) {
sched_yield();
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there may be a race if multiple threads try to init at the same. I think I specified the algorihtm incorrectly (slightly the first time). Here's what it should be:

if (is process inited) {
  if (test_and_set(is first thread)) {
      ... do your process initialization you have here
      is process initted = true;
   } else {
     // process is not initted, but someone else is already handling it.
     while (!process is inited) { sched_yield(); }
   }
}
// process is inited here. Yay!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_and_set should be replaced __sync_bool_compare_and_swap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants